//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "WNPlatform/inc/WNSurfaceManagerXWindows.h"
#include "WNPlatform/inc/WNSurfaceXWindows.h"

using namespace WNPlatform;

WNSurfaceManagerXWindows::~WNSurfaceManagerXWindows() {
    
}

WNSurfaceManager::WNSurfaceManagerError WNSurfaceManagerXWindows::Initialize() {
    XInitThreads();
    mDisplay = XOpenDisplay(NULL);    
    if(!mDisplay) {
        return(eSMENInitializationFailure);
    }
    mScreen = DefaultScreen(mDisplay);
    mRootWindow = RootWindow(mDisplay, mScreen);
    static int visual_attribs[] =
    {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
        GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
        GLX_RED_SIZE        , 8,
        GLX_GREEN_SIZE      , 8,
        GLX_BLUE_SIZE       , 8,
        GLX_ALPHA_SIZE      , 8,
        GLX_DEPTH_SIZE      , 24,
        GLX_STENCIL_SIZE    , 8,
        GLX_DOUBLEBUFFER    , True,
        GLX_SAMPLE_BUFFERS  , 1,
        GLX_SAMPLES         , 1,
        None
    };

    int fbcount = 0;
    GLXFBConfig *fbc = glXChooseFBConfig( mDisplay, DefaultScreen( mDisplay ), 
                                        visual_attribs, &fbcount );
    if ( !fbc )
    {
        return(eSMENInitializationFailure);
    }
    mFBConfig = fbc[0];
    XFree(fbc);
    mVisualInfo = glXGetVisualFromFBConfig( mDisplay, mFBConfig  );
    return(eWNOK);
}

WNSurfaceManager::WNSurfaceManagerError WNSurfaceManagerXWindows::CreateSurface(WN_UINT32 _x, WN_UINT32 _y, WN_UINT32 _width, WN_UINT32 _height, WNContainers::WNResourcePointer<WNSurface>& _surface) {
    WNContainers::WNResourcePointer<WNPlatform::WNSurfaceXWindows> ptr = WNContainers::WNAllocateResource1<WNPlatform::WNSurfaceXWindows, WNPlatform::WNSurfaceManagerXWindows&>(*this);
    if(!ptr->Initialize(_x, _y, _width, _height, mDisplay, mVisualInfo)) {
        return(eSMENInitializationFailure);
    }
    _surface = ptr;
    return(eWNOK);
}

WNSurfaceManager::WNSurfaceManagerError WNSurfaceManagerXWindows::Release() {
    return(eWNOK);
}

WNSurfaceManagerXWindows::WNSurfaceManagerXWindows() :
    mDisplay(WN_NULL),
    mRootWindow(0) {
}